package iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.service;

import org.json.JSONObject;

import java.util.List;

import iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.entity.Product;
import iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.entity.Trace;

public interface IProductService {
    /**
     * 生产商向数据库添加一个新的商品。
     *
     * @param newProduct 产品对象，包含新产品的信息。
     *                   必须包括以下属性：
     *                   <ul>
     *                       <li><b>productId</b> (String): 产品唯一标识符。</li>
     *                       <li><b>productName</b> (String): 产品名称。</li>
     *                       <li><b>qrCode</b> (byte[]): 产品二维码。</li>
     *                       <li><b>category</b> (String): 产品类别。</li>
     *                       <li><b>price</b> (double): 产品价格。</li>
     *                       <li><b>produceDate</b> (String): 产品生产日期。</li>
     *                       <li><b>state</b> (Integer): 产品状态。</li>
     *                   </ul>
     * @see Product
     * @return 一个布尔值，true 表示添加成功，false 表示添加失败：
     */
    Boolean addProduct(Product newProduct);

    /**
     * 生产商向数据库添加一个新的商品。
     *
     * @param productId 产品唯一标识符。
     * @see Product
     * @return 查询到的 Product，附带生产商图片。
     */
    Product getProductInfoById(String productId);

    /**
     * 生产商根据关键字在名称和分类查询商品。
     *
     * @param keyword 查询关键字。
     * @see Product
     * @return 查询到的 Product，附带生产商图片。
     */
    List<Product> searchProductsByNameOrCategory(String keyword);

    /**
     * 生产商向数据库添加一个新的商品。
     *
     * @param newProduct 新的产品信息，不管是否需要修改都要包含。<b>一定不能缺少产品唯一标识符 productId</b>。
     * @return 一个布尔值，true 表示更新成功，false 表示更新失败：
     * @see Product
     */
    Boolean updateProductInfo(Product newProduct);

    /**
     * 生产商向数据库删除一个新的商品，仅能删除未出厂产品。
     *
     * @param productId 产品唯一标识符。
     * @return 一个布尔值，true 表示删除成功，false 表示删除失败。
     */
    Boolean deleteProduct(String productId);

    /**
     * 获取数据库中所有的商品数据。
     *
     * @return 包含所有 Product 的 List。
     * @see Product
     */
    List<Product> getAllProducts();

    /**
     * 获取数据库中所有的商品数据。
     *
     * @param newProducts 所有新的产品。
     * @return 一个布尔值，true 表示新增成功，false 表示新增失败。
     * @see Product
     */
    Boolean importProductsFromOtherFiles(List<Product> newProducts);

    /**
     * 经销商仅能查询到等待出厂的产品。
     *
     * @return 包含所有状态为等待出厂的 Product 的 List。
     * @see Product
     */
    List<Product> getPendingProductsByDealer();

    /**
     * 经销商查询已购买但还未拍摄追溯照片的产品。
     *
     * @return 包含所有状符合条件的厂的 Product 的 List。
     * @see Product
     */
    List<Product> getPurchasedProductByDealer();

    /**
     * 经销商购买一件未出厂产品。
     *
     * @param productId 产品唯一标识符。
     * @return 一个布尔值，true 表示购买成功，false 表示购买失败。
     */
    Boolean purchaseByDealer(String productId);

    /**
     * 经销商批量购买未出厂产品。
     *
     * @param productIds 产品唯一标识符。
     * @return 一个布尔值，true 表示购买成功，false 表示购买失败。
     */
    Boolean purchaseByDealerInBulk(String[] productIds);

    /**
     * 消费者查询所有可被购买的产品。
     *
     * @return 一个布尔值，true 表示购买成功，false 表示购买失败。
     * 包含所有状态为未被购买的 Product 的 List。
     * @see Product
     */
    List<Product> getAvailableProductsByConsumer();

    /**
     * 消费者查询已购买但还未拍摄追溯照片的产品。
     *
     * @return 包含所有状符合条件的厂的 Product 的 List。
     * @see Product
     */
    List<Product> getPurchasedProductByConsumer();

    /**
     * 消费者购买一件未出厂产品。
     *
     * @param productId 产品唯一标识符。
     * @return 一个布尔值，true 表示购买成功，false 表示购买失败。
     */
    Boolean purchaseByConsumer(String productId);

    /**
     * 生产商、经销商和消费者向数据库添加商品的追溯照片。
     *
     * @param newTrace 追溯对象，包含新的追溯信息，
     *                 根据上传者身份必须包括以下属性：
     *                   <ul>
     *                       <li><b>productId</b>(String): 产品唯一标识符。</li>
     *                       <li><b>***Id</b>（Integer）: 上传者身份唯一标识符。</li>
     *                       <li><b>***Img</b>（byte[]）: 上传者拍摄的追溯照片。</li>
     *                   </ul>
     * @param role 用户身份标识符。
     * @see Trace
     * @return 一个布尔值，true 表示添加成功，false 表示添加失败。
     */
    Boolean addTraceabilityPicture(Trace newTrace, Integer role);

    /**
     * 请求查询追溯信息方法，需要用户输入<b>六位数字短信验证码</b>才能查询，
     * <b>验证码有效期为5分钟</b>
     *
     * @param userId 用户唯一标识符。
     * @param phoneNumber 用户电话号码。
     * @return 一个布尔值，true 表示请求成功，false 表示请求失败。
     */
    Boolean requestTraceability(Integer userId, String phoneNumber);

    /**
     * 验证查询追溯记录的请求。
     *
     * @param userId 用户唯一标识符。
     * @param productId 查询目标产品唯一标识符。
     * @param verifyCode 六位数字验证码，用于查询验证。
     * @return 一个包含查询结果的 JSON 对象，其字段及可能结果如下：
     * <ul>
     *     <li><b>success</b> (Boolean): 表示查询是否成功。</li>
     *     <li><b>message</b> (String): 查询结果详细信息
     *         <ul>
     *             <li><b>BAD REQUEST</b>: 服务器找不到查询请求，可能存在破解。</li>
     *             <li><b>验证码错误</b>: 用户输入验证码与服务器保存的不一致。</li>
     *             <li><b>验证码已过期</b>: 验证码有效期为5分钟。</li>
     *             <li><b>BAD RESULT</b>: 数据库中找不到相关追溯记录（不太可能发生）。</li>
     *             <li><b>查询到结果</b>: 查询成功。</li>
     *         </ul>
     *     </li>
     *     <li><b>resultTrace</b> (Trace): 查询成功的追溯记录。</li>
     *     <li><b>resultProduct</b> (Product): 查询成功一并返回产品基本信息。</li>
     * @see Trace
     * @see Product
     */
    JSONObject verifyTraceability(Integer userId, String productId, String verifyCode);
}
